
import redis
from setting import STATION_ROW_DATA_STACK, STATION_DATA_STACK, SEND_STATION_COMMAND_STACK
from crc import crc_verification
import logging
from atct_time_method import AtctTimeMethod
from serial_connect import SerialPortMethod
import threading
from db_method import DbMethod
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logger = logging.getLogger(__name__)

class RedisStarckMethod:

    def __init__(self) -> None:
        
        self.r = redis.Redis(host='localhost', port=6379, db=0)

    
    def station_data_stack(self):
        '''处理站点交来的数据'''

        data = b""

        while True:

            # logger.info('当前data: {}'.format(data))

            if self.r.llen(STATION_ROW_DATA_STACK) == 0 and data!=b'' and len(data)>2 and len(data) >= data[1]: # 当栈空且data有数据时不从栈中取数据

                    row_item = b''

            else:

                item = self.r.blpop(STATION_ROW_DATA_STACK)

                row_item = item[1]

            if row_item[:4] == b"ATCT": # 时间

                AtctTimeMethod(row_item[5:17].decode()).set_time_difference() # 设置时间差全局变量

                logger.info("重置时间差值")

            if data == b"" or len(data) <=2:  # data 为空时

                # logger.info("data 为空时")

                if row_item[:1] == b"\xe5":

                    data += row_item

                elif b'\xe5' in row_item:

                    index = row_item.index(b'\xe5')

                    data += row_item[index: ]

            elif data[:1] != b'\xe5': # data 不为空 且开头 不为 b'\xe5'

                if b'\xe5' in data: # 包含b'\xe5'

                    index = data.index(b'\xe5')

                    data = data[index: ] # 重置data

                else:

                    data = row_item

            elif data[1] > 36: # 长度标识过长为异常数据

                data = data[2:]

            elif len(data) < data[1]: # 当前命令长度小于指定长度

                data += row_item

                # logger.info(data)

            else: # 符合截取命令条件

                logger.info('符合截取命令条件')

                command = data[: data[1]].hex()

                if crc_verification(command):

                    self.r.rpush(STATION_DATA_STACK, command)

                    with DbMethod() as dm:

                        dm.insert_sensor_data(command)

                    logger.info("CRC验证通过: {}".format(command))

                else:

                    logger.error("CRC验证失败: {}".format(command))


                data = data[data[1]:] + row_item

    def send_command_to_sensor(self): # 下发指令到传感器

        while True:

            try:

                item = self.r.blpop(SEND_STATION_COMMAND_STACK)

                row_command = item[1]

                SerialPortMethod().send_row_data(row_command)

            except Exception as e:

                logger.error("下发指令时报错：{}".format(str(e)))
                logger.error("报错指令：{}".format(row_command.encode()))

            else:

                logger.info(f"下发指令：{row_command.encode()}")






if __name__ == "__main__":

    RedisStarckMethod().station_data_stack()

            
        